package net.sashag.nadlandroid;

import java.io.IOException;
import java.util.List;

import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.googlecode.androidannotations.annotations.AfterInject;
import com.googlecode.androidannotations.annotations.EBean;
import com.googlecode.androidannotations.annotations.RootContext;
import com.googlecode.androidannotations.annotations.rest.RestService;
import com.googlecode.androidannotations.api.Scope;

@EBean(scope = Scope.Singleton)
public class LocationHelper {
	
	@RestService protected GoogleGeocodingService googleGeocoder;
	@RootContext protected Context context;
	
	@AfterInject
	protected void initGeocoder() {
		googleGeocoder.setRestTemplate(new RestTemplate(true /*includeDefaultConverters*/));
		googleGeocoder.getRestTemplate().getMessageConverters().add(new MappingJacksonHttpMessageConverter());
	}
	
	private String googleGeocodePointAndReturnFirstAddress(double latitude, double longitude) {
		GoogleGeocodingReply reply = googleGeocoder.geocodeLocation(latitude, longitude, false);
		if (reply.status.equals("OK") && reply.results != null && reply.results.length > 0) {
			for (GoogleGeocodingResult result : reply.results) {
				Log.v("LocationHelper", "Potential match: " + result.formatted_address);
			}
			return reply.results[0].formatted_address;
		} else {
			return null; //Could not geocode the address
		}
	}
	
	public String geocodePointAndReturnFirstAddress(GeoPoint point, boolean useAndroidGeocoder) {
		if (!useAndroidGeocoder) {
			return googleGeocodePointAndReturnFirstAddress(point.getLatitudeE6()/1E6, point.getLongitudeE6()/1E6);
		}
		Geocoder geoCoder = new Geocoder(context);
		float latitude = point.getLatitudeE6()/1E6f;
		float longitude = point.getLongitudeE6()/1E6f;
		try {
			List<Address> results = geoCoder.getFromLocation(latitude, longitude, 1);
			if (results.size() == 0) {
				return null;
			} else {
				Address result = results.get(0);
				String address = result.getAddressLine(0);
				address += "\n" + result.getLocality();
				return address;
			}
		} catch (IOException e) {
			return null;
		}
	}
	
	public Location geocodeAddressAndReturnFirstPoint(String address) {
		Geocoder geoCoder = new Geocoder(context);
		try {
			List<Address> potentialLocations = geoCoder.getFromLocationName(address, 1);
			if (potentialLocations.size() == 0) {
				return null;
			} else {
				Address result = potentialLocations.get(0);
				Location location = new Location("geocoded");
				location.setLatitude(result.getLatitude());
				location.setLongitude(result.getLongitude());
				return location;
			}
		} catch (IOException e) {
			return null;
		}
	}
	
}
